﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once

#include "IGeometry.h"

namespace gcmp
{
    class Vector2d;
    class IMesh : public IGeometry
    {
        DEFINE_CAST_DERIVED(gcmp::IMesh, gcmp::IGeometry);
    public:

        /*!
        *@brief  创建mesh
        *@param[in] const std::vector<Vector3d>& vertices        顶点的数组
        *@param[in] const std::vector<Vector3d>& vertexNormals   顶点法向的数组
        *@param[in] const std::vector<Vector2d>& vertexUVs             纹理坐标的数组
        *@param[in] const std::vector<int>& triangleVertexIndices  顶点索引，每三个索引一组作为三角片
        *@param[in] const std::vector<int>& triangleVertexNormalIndices   顶点法向索引，每三个索引一组作为三角片
        *@param[in] const std::vector<int>& triangleVertexUVIndices   纹理坐标的索引，每三个索引一组作为三角片
        *@return OwnerPtr<IMesh>
        */
        GCMP_GEOMETRY_INTERFACE_EXPORT static OwnerPtr<IMesh> Create(const std::vector<Vector3d>& vertices,
            const std::vector<Vector3d>& vertexNormals,
            const std::vector<Vector2d>& vertexUVs,
            const std::vector<int>& triangleVertexIndices,
            const std::vector<int>& triangleVertexNormalIndices,
            const std::vector<int>& triangleVertexUVIndices);

        /*!
     *@brief   读取读取obj文件到IMesh（包括几何结构、纹理、法向量）
     *@param[in] filePath 读取的obj文件路径
     *@return OwnerPtr<IMesh>
     */
        GCMP_GEOMETRY_INTERFACE_EXPORT static OwnerPtr<IMesh>  ReadObjTriMesh(const std::wstring& filePath);

        /*!
        *@brief  获取所有顶点
        */
        virtual const std::vector<Vector3d>& GetVertices() const = 0;

        /*!
        *@brief  设置所有顶点
        */
        virtual bool SetVertices(const std::vector<Vector3d>& vertices) = 0;

        /*!
        *@brief  获取所有顶点的法向
        */
        virtual const std::vector<Vector3d>& GetVertexNormals() const = 0;

        /*!
        *@brief  设置所有顶点的法向
        */
        virtual bool SetVertexNormals(const std::vector<Vector3d>& normals) = 0;

        /*!
        *@brief  获取所有顶点的UV
        */
        virtual const std::vector<Vector2d>& GetVertexUVs() const = 0;

        /*!
        *@brief  设置所有顶点的UV
        */
        virtual bool SetVertexUVs(const std::vector<Vector2d>& uvs) = 0;

        /*!
        *@brief  获取所有的顶点索引，顶点法向索引，顶点UV索引
        */
        virtual void GetTriangleVertexIndices(std::vector<int>& vertexIndices,
                                              std::vector<int>& vertexNormalIndices,
                                              std::vector<int>& vertexUVIndices) const = 0;

        /*!
        *@brief  设置所有的顶点索引，顶点法向索引，顶点UV索引
        */
        virtual bool SetTriangleVertexIndices(const std::vector<int>& vertexIndices,
                                              const std::vector<int>& vertexNormalIndices,
                                              const std::vector<int>& vertexUVIndices) = 0;

        /*！
        * @brief      消除网格中在阈值范围内的重合点和退化的三角面
        * @return    true表示执行成功，否则为false。
        * @attention  Mesh体系设置统一容差，系统默认距离容差为1e-4,用户可以通过容差类MeshTolerance的SetDistTol函数来设置距离容差
        *             设置方式为MeshTolerance::SetDistTol(double distTol)
        */
        virtual bool UniqueVert() = 0;

        /*!
         *@brief  计算面积
         *@return 面积
         */
        virtual double Area() const = 0;

        /*!
        *@brief  计算体积
        *@return 体积
        */
        virtual double Volume() const = 0;

        /*!
        *@brief     获取边界索引信息
        *@return    返回边缘点索引
        */
        virtual std::vector<std::vector<int>> GetBoundarys()const = 0;

        /*!
        *@brief    判断网格是否封闭
        *@return   true 封闭 false 不封闭
        */
        virtual bool IsClosed() const = 0;
      
    public:
        virtual ~IMesh() {}
    };
}
